/**
 * 生成请求签名及uri编码
 */
const crypto = require('crypto'),
  log = require('../util/log'),
  getHtml = require('../util/getHtml')

// 兼容php的urlencode
function fullEncodeURIComponent(str) {
  var rv = encodeURIComponent(str).replace(/[!'()*~]/g, function (c) {
    return '%' + c.charCodeAt(0).toString(16).toUpperCase();
  });
  return rv.replace(/\%20/g, '+');
}

/**
 * 生成请求签名
 *
 * @param {object} reqParams, 由url.parse解析出来的对象内容,描述请求的位置和url及参数等信息的对象
 * @param {object} postParams post表单内容
 * @param {string} secretKey 开发者中心的SK
 * @return {string} 签名值
 */
var singKey = function (reqParam, postParmas, secretKey) {
  var basekey = "";
  var method = reqParam.method.toUpperCase();
  var baseurl = reqParam.href;
  var query = reqParam.query || false;
  var param = {};
  var paramStr = '';
  if (query) {
    query = querystring.parse(query);
    for (var key in query) {
      param[key] = query[key];
    }
  }
  if (postParmas) {
    for (var key in postParmas) {
      param[key] = postParmas[key];
    }
  }
  var keys = Object.keys(param).sort();
  keys.forEach(function (key) {
    paramStr += key + "=" + param[key];
  })
  basekey = method + baseurl + paramStr + secretKey;
  var md5 = crypto.createHash('md5');
  basekey = fullEncodeURIComponent(basekey);
  md5.update(basekey);
  return md5.digest('hex');
}

var BaiduPush = function (obj) {
  if (!(this instanceof BaiduPush)) {
    return new BaiduPush(obj)
  }
  this.apikey = obj.apikey || ''
  this.secretKey = obj.secretKey || ''
}

BaiduPush.prototype.statisticDevice = function () {
  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000),
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/report/statistic_device'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/report/statistic_device',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

BaiduPush.prototype.pushAll = function (_obj) {
  _obj = _obj || {}
  if (!_obj.description) {
    return new Promise((resolve, reject) => {
      reject('缺少description')
    })
  }

  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000),
    msg_type: _obj.msg_type || 0,
    msg: JSON.stringify({
      title: _obj.title || '',
      description: _obj.description
    })
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/push/all'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/push/all',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

BaiduPush.prototype.reportQueryMsgStatus = function () {
  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000),
    msg_id: '7173644595087312739'
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/report/query_msg_status'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/report/query_msg_status',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

BaiduPush.prototype.appQueryTags = function () {
  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000)
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/app/query_tags'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/app/query_tags',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

BaiduPush.prototype.tagDeviceNum = function (_obj) {
  _obj = _obj || {}
  if (!_obj.tag) {
    return new Promise((resolve, reject) => {
      reject('缺少tag')
    })
  }

  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000),
    tag: _obj.tag
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/tag/device_num'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/tag/device_num',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

BaiduPush.prototype.appCreateTag = function (_obj) {
  _obj = _obj || {}
  if (!_obj.tag) {
    return new Promise((resolve, reject) => {
      reject('缺少tag')
    })
  }

  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000),
    tag: _obj.tag
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/app/create_tag'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/app/create_tag',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

BaiduPush.prototype.tagAddDevices = function (_obj) {
  _obj = _obj || {}
  if (!_obj.tag) {
    return new Promise((resolve, reject) => {
      reject('缺少tag')
    })
  }
  if (!_obj.channel_ids) {
    return new Promise((resolve, reject) => {
      reject('缺少channel_ids')
    })
  }

  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000),
    tag: _obj.tag,
    channel_ids: JSON.stringify(_obj.channel_ids)
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/tag/add_devices'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/tag/add_devices',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

BaiduPush.prototype.appDelTag = function (_obj) {
  _obj = _obj || {}
  if (!_obj.tag) {
    return new Promise((resolve, reject) => {
      reject('缺少tag')
    })
  }

  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000),
    tag: _obj.tag
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/app/del_tag'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/app/del_tag',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

BaiduPush.prototype.pushBatchDevice = function (_obj) {
  _obj = _obj || {}
  if (!_obj.channel_ids) {
    return new Promise((resolve, reject) => {
      reject('缺少channel_ids')
    })
  }
  if (!_obj.description) {
    return new Promise((resolve, reject) => {
      reject('缺少description')
    })
  }

  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000),
    channel_ids: JSON.stringify(_obj.channel_ids),
    msg_type: _obj.msg_type || 0,
    msg: JSON.stringify({
      title: _obj.title || '',
      description: _obj.description
    })
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/push/batch_device'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/push/batch_device',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

BaiduPush.prototype.pushTags = function (_obj) {
  _obj = _obj || {}
  if (!_obj.tag) {
    return new Promise((resolve, reject) => {
      reject('缺少tag')
    })
  }
  if (!_obj.description) {
    return new Promise((resolve, reject) => {
      reject('缺少description')
    })
  }

  var obj = {
    apikey: this.apikey,
    timestamp: Math.floor(new Date().getTime() / 1000),
    type: 1,
    tag: _obj.tag,
    msg_type: _obj.msg_type || 0,
    msg: JSON.stringify({
      title: _obj.title || '',
      description: _obj.description
    })
  }

  obj.sign = singKey({
    method: 'post',
    href: 'http://api.tuisong.baidu.com/rest/3.0/push/tags'
  }, obj, this.secretKey)

  var data = ''
  for (var key in obj) {
    data += key + '=' + obj[key] + '&'
  }
  data = data.substring(0, data.length - 1)
  return new Promise((resolve, reject) => {
    getHtml({
      url: 'http://api.tuisong.baidu.com/rest/3.0/push/tags',
      data: data,
      headers: {
        'User-Agent': 'BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0',
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then(result => {
      resolve(JSON.parse(result))
    }, result => {
      reject(result)
    })
  })
}

module.exports = BaiduPush
